package cn.e4j.modular.system.controller;

import cn.e4j.core.base.controller.BaseController;
import cn.e4j.core.dto.Dtos;
import cn.e4j.core.dto.impl.Dto;
import cn.e4j.core.dto.requestDtoResolver.DtoParam;
import cn.e4j.core.dto.requestDtoResolver.DtoWapper;
import cn.e4j.core.quartz.QuartzUtil;
import cn.e4j.core.reqres.response.PageReData;
import cn.e4j.core.reqres.response.ResponseData;
import cn.e4j.core.util.ClassUtil;
import cn.e4j.core.util.InvokeUtil;
import cn.e4j.core.util.SpringContextHolder;
import cn.e4j.modular.system.entity.SysTask;
import cn.e4j.modular.system.service.SysTaskService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.*;

/**
 * 定时任务控制类
 *
 * @author yuan_rz
 * @Date 2019/03/11 13:51
 */
@Controller
@RequestMapping("/sys/task")
public class SysTaskController extends BaseController {

    @Autowired
    private SysTaskService sysTaskService;

    @Resource
    private Scheduler scheduler;

    /**
     * 初始化定时任务
     */
    @PostConstruct
    public void initTask() {
        //System.out.println(".........initTask...........");

        //定时任务启动
        Dto dto = Dtos.newDto();
        dto.put("TASK_STATUS", "1");

        try {

            List<SysTask> listData = sysTaskService.initTask(dto);
            for (SysTask sysTask : listData) {
                //传递参数
                Map<String, String> params = new HashMap<>();
                params.put("taskid", sysTask.getID());

                QuartzUtil.createJob(scheduler, sysTask, params);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void preDestroy() {
        //System.out.println(".........preDestroy...........");
    }

    /**
     * 跳转页面
     */
    @RequiresPermissions("sys:task:init")
    @RequestMapping(value = {"", "init"})
    public String index() {
        return "/pc/system/task.html";
    }

    /**
     * 查询列表数据
     */
    @RequestMapping("/getListData")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData getListData(@DtoParam DtoWapper dtoWapper) {
        Page<Object> page = dtoWapper.getPage();
        Dto inDto = dtoWapper.getDto();
        List<SysTask> result = sysTaskService.getListData(page, inDto);
        return new PageReData(page, result);
    }

    /**
     * 添加数据
     */
    @RequestMapping("/addData")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData addData(SysTask sysTask) {
        sysTaskService.addData(sysTask);
        return SUCCESS_TIP;
    }

    /**
     * 修改数据
     */
    @RequestMapping("/editData")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData editData(SysTask sysTask) {

        // 修改的时候 要修改任务的规则

        sysTaskService.editData(sysTask);
        return SUCCESS_TIP;
    }

    /**
     * 删除数据
     */
    @RequestMapping("/deleteData")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData deleteData(SysTask sysTask) {
        QuartzUtil.deleteJob(scheduler, sysTask.getTASK_CLASS());
        sysTaskService.deleteData(sysTask);
        return SUCCESS_TIP;
    }

    /**
     * 批量删除数据
     */
//    @RequestMapping("/deleteDataBatch")
//    @RequiresPermissions("sys:task:init")
//    @ResponseBody
//    public ResponseData deleteDataBatch(@DtoParam DtoWapper dtoWapper) {
//        Dto inDto = dtoWapper.getDto();
//        List<SysTask> sysTaskList = inDto.getReqList(SysTask.class);
//        sysTaskService.deleteDataBatch(sysTaskList);
//        return SUCCESS_TIP;
//    }

    /**
     * 启动任务
     */
    @RequestMapping("/runTask")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData runTask(SysTask sysTask) {

        try {

            sysTask.setTASK_STATUS("1");
            if (QuartzUtil.checkJobKey(scheduler, sysTask.getTASK_CLASS())) {
                QuartzUtil.resumeJob(scheduler, sysTask.getTASK_CLASS());
            } else {
                Map<String, String> params = new HashMap<>();
                params.put("taskid", sysTask.getID());
                QuartzUtil.createJob(scheduler, sysTask, params);
            }

            sysTaskService.runTask(sysTask);

        } catch (ParseException e) {
            e.printStackTrace();
            return ResponseData.error("CronExpression is not correct");
        } catch (SchedulerException e) {
            e.printStackTrace();
            return ResponseData.error("run task error");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return ResponseData.error("class is not found");
        }
        return SUCCESS_TIP;
    }

    /**
     * 停止任务
     */
    @RequestMapping("/stopTask")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData stopTask(SysTask sysTask) {
        try {
            QuartzUtil.pauseJob(scheduler, sysTask.getTASK_CLASS());
            sysTaskService.stopTask(sysTask);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return ResponseData.error("stop task error");
        }
        return SUCCESS_TIP;
    }

    /**
     * 执行一次
     */
    @RequestMapping("/runTaskOnce")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData runTaskOnce(SysTask sysTask, @DtoParam DtoWapper dtoWapper) {
        Dto inDto = dtoWapper.getDto();
        try {

            //传递参数
            Map<String, String> params = new HashMap<>();
            params.put("taskid", sysTask.getID());

            QuartzUtil.runOnce(scheduler, sysTask, params);

            // sysTaskService.runTaskOnce(sysTask, inDto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS_TIP;
    }

    /**
     * 根据表达式取最近五次运行时间，有错则提示
     */
    @RequestMapping("/lastFiveTimes")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData lastFiveTimes(String cron) {
        List<String> list = new ArrayList<>();
        //验证cron表达式
        try {
            list = sysTaskService.lastFiveTimes(cron);
        } catch (ParseException e) {
            //返回cron表达式不正确提示
            e.printStackTrace();
            return ResponseData.success("CronExpression is not correct");
        }
        return ResponseData.success(list);
    }

    /**
     * 获取类文件列表
     */
    @RequestMapping("/getClassList")
    @RequiresPermissions("sys:task:init")
    @ResponseBody
    public ResponseData getFileList() {
        Set<Class<?>> classSet = ClassUtil.getClassSet("cn.e4j.core.quartz.job");
        List<Dto> list = new ArrayList<>();
        try {
            for (Class c : classSet) {
                Dto dto = Dtos.newDto();
                dto.put("value", InvokeUtil.invokeBeanMethod(c.getSimpleName() + ",getDescribe"));
                dto.put("code", c.getSimpleName());
                list.add(dto);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResponseData.success(list);
    }


}
